#! /bin/sh
# PCP QA Test No. 066
# Test PMCD correctly restores original access control list after
# reconfiguration with a bad config file.
#
# Copyright (c) 1995-2002 Silicon Graphics, Inc.  All Rights Reserved.
#

seq=`basename $0`
echo "QA output created by $seq"

# get standard filters
. ./common.product
. ./common.filter
. ./common.check

rm -f $seq.out
_get_libpcp_config
if $ipv6 ; then
    ln $seq.out.ipv6 $seq.out || exit 1
else
    ln $seq.out.nonipv6 $seq.out || exit 1
fi

status=0
trap "_interrupt" 1 2 3 15	# refactor-ok
trap "_cleanup; exit \$status" 0

# don't need to regenerate config.default with pmlogconf
#
export PMLOGGER_CHECK_SKIP_LOGCONF=yes

_stop_auto_restart pmcd

# real QA test starts here

signal=$PCP_BINADM_DIR/pmsignal
log=$PCP_PMCDLOG_PATH
_needclean=true
LOCALHOST=`hostname`
LOGGING_DIR="$PCP_ARCHIVE_DIR"

_filter_log()
{
    sleep 1
    _filter_pmcd_log <$log \
    | grep -v "^access violation from host" \
    | grep -v "^endclient client" \
    | sed \
	-e 's/^$//' \
	-e '/^00[08]:/d' \
	-e '/^ClientsAttributes(/d' \
	-e '/^linux/s/\/var\//\/usr\//' \
	-e '/^sample/s/.*/sample agent.../' \
	-e '/client connection from/,/^$/d' \
	-e 's/[1-4] dso/X dso/' \
	-e 's/00001983  0000ffff/83190000  ffff0000/' \
	-e "s;$PCP_PMCDCONF_PATH;\$PCP_PMCDCONF_PATH;g" \
	-e "s;$PCP_VAR_DIR;\$PCP_VAR_DIR;g" \
	-e 's;$PCP_PMDAS_DIR/pmcd/;;' \
	-e "s;\.$DSO_SUFFIX;.\$DSO_SUFFIX;g" \
	-e '/UNIX_DOMAIN_SOCKET/d' \
	-e '/unix:/d' \
	-e '/ContactAgents: agent/d' \
    | $PCP_AWK_PROG '
/localhost/		{ sub(/^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$/,"MYIPADDR",$5)
			  sub(/^[0-9a-f:][0-9a-f:]*%[0-9a-z]+$/,"MYIPADDR",$5)
			  sub(/^[0-9a-f:][0-9a-f:]*$/,"MYIPADDR",$5)
			  sub(/^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$/,"MYHOSTMASK",$6)
			  sub(/^[0-9a-f:][0-9a-f:]*$/,"MYHOSTMASK",$6) }
			{ print }'
}

_interrupt()
{
    echo "Interrupted!"
    _exit 1
}

_cleanup()
{
    if [ $_needclean ]
    then
	$sudo $PCP_RC_DIR/pmcd stop 2>&1 | _filter_pcp_stop
	$sudo $PCP_RC_DIR/pmlogger stop 2>&1 | _filter_pcp_stop
	_restore_config $PCP_PMCDCONF_PATH
	pmafm $LOGGING_DIR/$LOCALHOST/Latest remove >$tmp.cmd 2>&1 \
	    && $sudo sh $tmp.cmd
	echo "Restarting pmcd"
	echo "+++ restarting pmcd `date` +++" >>$seq_full
	_service pmcd restart 2>&1 \
	| tee -a $seq_full \
	| _filter_pcp_restart
	_wait_for_pmcd
	_restore_auto_restart pmcd
	_service pmlogger restart 2>&1 \
	| tee -a $seq_full \
	| _filter_pcp_restart
	_wait_for_pmlogger
	_needclean=false
    fi
    rm -f $tmp $tmp.*
}

_myfilter_config()
{
    sed \
	-e "s/$other1/OTHER1/" \
	-e "s/$other2/OTHER2/" \
	-e "s;$PCP_RC_DIR;\$PCP_RC_DIR;g" \
	-e "s;$PCP_PMDAS_DIR;\$PCP_PMDAS_DIR;g" \
	-e "/^$PCP_PLATFORM/s/.*/[platform PMDA]/" \
	-e 's;$PCP_PMDAS_DIR/pmcd/;;' \
	-e "s;\.$DSO_SUFFIX;.\$DSO_SUFFIX;g" \
	-e '/Installed by PCP QA/s/ on .*/ on DATE/' \
    | _filter_pmcd_log
}

pmafm $LOGGING_DIR/$LOCALHOST/Latest remove >$tmp.cmd 2>&1 \
    && $sudo sh $tmp.cmd

cat >$tmp  <<End-of-File
# Need the pmcd PMDA so that "init" restart can start pmlogger
# the OS PMDA has to be there so that the default logging config works
# Installed by PCP QA test $seq on `date`
#
End-of-File

# order MATTERS ... platform PMDA first, then pmcd PMDA
#
if [ $PCP_PLATFORM = linux ]
then
    cat >>$tmp  <<End-of-File
linux   60      dso     linux_init      $PCP_PMDAS_DIR/linux/pmda_linux.so
pmcd	2	dso	pmcd_init	$PCP_PMDAS_DIR/pmcd/pmda_pmcd.so
End-of-File
elif [ $PCP_PLATFORM = darwin ]
then
    cat >>$tmp  <<End-of-File
darwin	78	dso	darwin_init	$PCP_PMDAS_DIR/darwin/pmda_darwin.dylib
pmcd	2	dso	pmcd_init	$PCP_PMDAS_DIR/pmcd/pmda_pmcd.dylib
End-of-File
elif [ $PCP_PLATFORM = solaris ]
then
    cat >>$tmp  <<End-of-File
solaris	75	dso	solaris_init	$PCP_PMDAS_DIR/solaris/pmda_solaris.so
pmcd	2	dso	pmcd_init	$PCP_PMDAS_DIR/pmcd/pmda_pmcd.so
End-of-File
elif [ $PCP_PLATFORM = freebsd ]
then
    cat >>$tmp  <<End-of-File
freebsd	85	dso	freebsd_init	$PCP_PMDAS_DIR/freebsd/pmda_freebsd.so
pmcd	2	dso	pmcd_init	$PCP_PMDAS_DIR/pmcd/pmda_pmcd.so
End-of-File
elif [ $PCP_PLATFORM = openbsd ]
then
    cat >>$tmp  <<End-of-File
openbsd	139	dso	openbsd_init	$PCP_PMDAS_DIR/openbsd/pmda_openbsd.so
pmcd	2	dso	pmcd_init	$PCP_PMDAS_DIR/pmcd/pmda_pmcd.so
End-of-File
else
    echo "Error - need pmcd.conf setup for PCP_PLATFORM $PCP_PLATFORM"
    exit 1
fi

cat >>$tmp  <<End-of-File

[access]
allow localhost: all;
disallow 131.25.*: store;
disallow *: all;

End-of-File

eval `./getpmcdhosts -L -n 2 \
      | $PCP_AWK_PROG '{ if (NF == 2) printf("other1=%s other2=%s\n",$1,$2); }'`

if [ -z "$other1" -o -z "$other2" ]
then
    _notrun "Cannot find two remote hosts running pmcd"
    # NOTREACHED
fi

_save_config $PCP_PMCDCONF_PATH
echo "+++ stopping pmcd `date` +++" >>$seq_full
if ! _service pmlogger stop 2>&1; then _exit 1; fi \
| tee -a $seq_full \
| _filter_pcp_stop
_wait_pmlogger_end || _exit 1
if ! _service pmcd stop 2>&1; then _exit 1; fi \
| tee -a $seq_full \
| _filter_pcp_stop
_wait_pmcd_end || _exit 1
$sudo $signal -a pmgadgets pmchart pmview >/dev/null 2>&1
$sudo cp $tmp $PCP_PMCDCONF_PATH
# try to dodge bind: Address already in use
[ $PCP_PLATFORM = solaris ] && sleep 10
echo "+++ starting pmcd `date` +++" >>$seq_full
# cannot use _service here as we don't want systemctl in the picture
# because pmcd will have trouble starting ...
#
$sudo $PCP_RC_DIR/pmcd start 2>&1 | tee -a $seq_full | _filter_pcp_start
$sudo $PCP_RC_DIR/pmlogger start 2>&1 | tee -a $seq_full | _filter_pcp_start
_wait_for_pmcd || _exit 1
_wait_for_pmlogger || _exit 1
echo "first config:"
_myfilter_config  <$PCP_PMCDCONF_PATH
echo

cat >>$tmp  <<End-of-File

disallow $other1: store;
allow $other2: all;

ddiissallow misspelt: all;
End-of-File

$sudo cp $tmp $PCP_PMCDCONF_PATH
echo "second config:"
_myfilter_config <$PCP_PMCDCONF_PATH

echo
$sudo $signal -a -s HUP pmcd
_wait_for_pmcd || _exit 1

# wait for PMCD to finish writing log (or 5 seconds)
for t in 1 2 3 4 5
do
    if [ ! -f $log ]
    then
	echo "$log missing!"
	ls -l `dirname $log`
	cat ${log}.prev >>$seq_full
	exit
    elif [ `grep -E '^Host access' $log | wc -l` = 2 ]
    then
	break
    fi
    sleep 1
done

_filter_log
